package gdma.hqdes.webapp;

import common.exception.ForbiddenException;
import gdma.hqdes.bean.Unit;
import gdma.hqdes.service.ProjectService;
import gdma.hqdes.service.UnitService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import sindconsole.auth.bean.User;
import sindconsole.auth.bean.UserPrincipal;

import java.util.Date;
import java.util.List;

@Configuration
@EnableScheduling
public class HqdesWebapp implements WebMvcConfigurer {

    public static final String SUBJECT_UNIT = "subjectUnit";

    public static final String CURRENT_PROJECTS = "currentProjects";

    @Autowired
    UnitService unitService;

    @Autowired
    ProjectService projectService;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new HandlerMethodArgumentResolver() {
            @Override
            public boolean supportsParameter(MethodParameter methodParameter) {
                return Unit.class.isAssignableFrom(methodParameter.getParameterType()) && SUBJECT_UNIT.equals(methodParameter.getParameterName());
            }
            @Override
            public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
                Subject subject = SecurityUtils.getSubject();
                if(subject == null) throw new ForbiddenException();
                UserPrincipal principal = (UserPrincipal) subject.getPrincipal();
                if(principal == null) throw new ForbiddenException();
                User user = principal.getUser();
                return user.getUnitId() != null ? unitService.getUnit(user.getUnitId()) : null;
            }
        });

        argumentResolvers.add(new HandlerMethodArgumentResolver() {
            @Override
            public boolean supportsParameter(MethodParameter methodParameter) {
                return List.class.isAssignableFrom(methodParameter.getParameterType()) && CURRENT_PROJECTS.equals(methodParameter.getParameterName());
            }
            @Override
            public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
                Subject subject = SecurityUtils.getSubject();
                if(subject == null) throw new ForbiddenException();
                UserPrincipal principal = (UserPrincipal) subject.getPrincipal();
                if(principal == null) throw new ForbiddenException();
                User user = principal.getUser();
                Unit unit = unitService.getUnit(user.getUnitId());
                int scope = unit != null ? unit.getScope() : Unit.SCOPE_MUNICIPAL;
                return projectService.getActiveProjects(new Date(), scope);
            }
        });

    }

}
